from flask import Blueprint, request, jsonify, make_response
from werkzeug.security import generate_password_hash, check_password_hash
import uuid
from flask import current_app
from backend.utils import api_response
from backend.models import db, User
from flask_jwt_extended import create_access_token, set_access_cookies, unset_jwt_cookies

auth_bp = Blueprint('auth', __name__, url_prefix='/api/auth')


@auth_bp.route('/register', methods=['POST'])
def register():
    """用户注册"""
    data = request.json
    if not data:
         return api_response(code=400, message="请求体不能为空")

    required_fields = ['username', 'password']
    if not all(field in data for field in required_fields):
        return jsonify({"error": "缺少必要字段"}), 400

    # 检查用户名是否已存在
    if User.query.filter_by(username=data['username']).first():
        return jsonify({"error": "用户名已存在"}), 409

    # 创建新用户，默认角色为 'public'
    try:
        new_user = User(
            username=data['username'],
            # --- 关键：新注册用户默认角色为 'public' ---
            role='public',
            apikey=str(uuid.uuid4()) # 生成唯一 API Key
            # quota 使用模型默认值
        )
        # 检查生成的 API Key 是否唯一 (极小概率重复)
        while User.query.filter_by(apikey=new_user.apikey).first():
            new_user.apikey = str(uuid.uuid4())

        new_user.set_password(data['password'])

        db.session.add(new_user)
        db.session.commit()
        current_app.logger.info(f"New user registered: {new_user.username}")

        # 返回成功信息和生成的 API Key
        return api_response(data={'apikey': new_user.apikey}, code=201, message="注册成功")

    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"Error during user registration: {e}", exc_info=True)
        return api_response(code=500, message=f"注册时发生错误: {e}")


@auth_bp.route('/login', methods=['POST', 'OPTIONS'])
def login():
    if request.method == 'OPTIONS':
        return _build_cors_preflight_response()
    """用户登录（获取JWT）"""
    data = request.json
    print(data)
    if not data or 'username' not in data or 'password' not in data:
        return api_response(code=400, message="需要提供 username 和 password")

    user = User.query.filter_by(username=data.get('username')).first()

    if not user or not check_password_hash(user.password, data.get('password')):
        print(user.role)
        print(data.get('role'))
        return jsonify({
            "code": 401,
            "message": "用户名或密码错误"
        }), 401

    # 用户名密码正确，生成 JWT
    try:
        # identity 存储用户 ID，additional_claims 存储角色等信息
        access_token = create_access_token(
            identity=str(user.id),
            additional_claims={"role": user.role}
        )
        current_app.logger.info(f"User logged in: {user.username}, Role: {user.role}")

        # 创建响应体，包含用户信息和 Token (可选，因为会设置 Cookie)
        response_data = {
            "user": {'id': user.id, 'username': user.username, 'role': user.role},
            "token": access_token, # 客户端调试用，生产环境可移除
            "api_key": user.apikey # 同时返回 API Key 方便用户
        }
        response = make_response(api_response(data=response_data, message="登录成功")[0]) # 获取 jsonify 的字典内容
        response.status_code = 200 # 设置状态码

        # 将 JWT 设置到 HttpOnly Cookie 中
        set_access_cookies(response, access_token)
        return response

    except Exception as e:
        current_app.logger.error(f"Error during login for user {data.get('username')}: {e}", exc_info=True)
        return api_response(code=500, message=f"登录时发生错误: {e}")

@auth_bp.route('/logout', methods=['POST'])
def logout():
    """用户登出（清除JWT Cookie）"""
    response = make_response(api_response(message="登出成功")[0])
    response.status_code = 200
    unset_jwt_cookies(response) # 清除 JWT cookies
    current_app.logger.info("User logged out")
    return response

def _build_cors_preflight_response():
    response = make_response()
    response.headers.add("Access-Control-Allow-Origin", "http://localhost:5173")
    response.headers.add("Access-Control-Allow-Headers", "Content-Type,Authorization")
    response.headers.add("Access-Control-Allow-Methods", "POST, OPTIONS")
    response.headers.add("Access-Control-Expose-Headers", "Authorization, Set-Cookie")
    response.headers.add("Vary", "Origin")
    response.headers.add("Access-Control-Allow-Credentials", "true")

    return response